package org.example.chatroom.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.example.chatroom.common.pojo.dataobject.Dialogue;
import org.example.chatroom.common.pojo.dataobject.DialogueUser;
import org.example.chatroom.common.pojo.dataobject.Message;
import org.example.chatroom.common.pojo.dataobject.UserInfo;
import org.example.chatroom.common.pojo.response.DUserResponse;
import org.example.chatroom.common.pojo.response.DialogueResponse;
import org.example.chatroom.mapper.DialogueMapper;
import org.example.chatroom.mapper.DialogueUserMapper;
import org.example.chatroom.mapper.MessageMapper;
import org.example.chatroom.mapper.UserMapper;
import org.example.chatroom.service.DialogueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: LIUYANJIAO
 * Date: 2025-06-24
 * Time: 9:50
 */
@Service
@Slf4j
public class DialogueServiceImpl implements DialogueService {
    @Autowired
    private DialogueMapper dialogueMapper;
    @Autowired
    private DialogueUserMapper dialogueUserMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private DataSourceTransactionManager transactionManager;


    @Override
    public List<DialogueResponse> getdialoguelist(Integer userId) {
        // 1. 查询当前用户参与的所有会话关联记录
        QueryWrapper<DialogueUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DialogueUser::getUserId, userId);
        List<DialogueUser> dialogueUsers = dialogueUserMapper.selectList(queryWrapper);

        // 2. 提取所有对话id，用于查询对话详情
        List<Integer> dialogueIds = dialogueUsers.stream()
                .map(DialogueUser::getDialogueId)
                .distinct() // 去重，避免重复查相同dialogue_id
                .collect(Collectors.toList());

        // 3. 查询对话详情（这里主要用lastTime，可按需扩展）
        QueryWrapper<Dialogue> dialogueQuery = new QueryWrapper<>();
        dialogueQuery.lambda().in(Dialogue::getId, dialogueIds);
        List<Dialogue> dialogues = dialogueMapper.selectList(dialogueQuery);
        Map<Integer, Dialogue> dialogueMap = dialogues.stream()
                .collect(Collectors.toMap(Dialogue::getId, d -> d));

        // 4. 处理每个对话，查询参与用户信息并组装响应
        List<DialogueResponse> dialogueResponses = new ArrayList<>();
        for (Integer dialogueId : dialogueIds) {
            DialogueResponse response = new DialogueResponse();
            // 设置对话截止时间
            Dialogue dialogue = dialogueMap.get(dialogueId);
            if (dialogue != null) {
                response.setLastTime(dialogue.getLastTime().atStartOfDay());
            }

            // 查询该对话下所有参与用户（排除当前用户）
            QueryWrapper<DialogueUser> duQuery = new QueryWrapper<>();
            duQuery.lambda()
                    .eq(DialogueUser::getDialogueId, dialogueId)
                    .ne(DialogueUser::getUserId, userId);
            List<DialogueUser> relatedDu = dialogueUserMapper.selectList(duQuery);

            // 提取这些用户的id，批量查UserInfo
            List<Integer> relatedUserIds = relatedDu.stream()
                    .map(DialogueUser::getUserId)
                    .collect(Collectors.toList());
            QueryWrapper<UserInfo> userQuery = new QueryWrapper<>();
            userQuery.lambda().in(UserInfo::getId, relatedUserIds);
            List<UserInfo> userInfos = userMapper.selectList(userQuery);

            //添加最后一条信息
            QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
            messageQueryWrapper.lambda().eq(Message::getDialogueId,dialogueId)
                    .orderByDesc(Message::getSendTime).last("LIMIT 1");
            Message message = messageMapper.selectOne(messageQueryWrapper);
            if(message==null){
                response.setContent(null);
            }
            else {
                response.setContent(message.getContent());
            }

            // 转换为DUserResponse
            List<DUserResponse> dUserResponses = userInfos.stream().map(ui -> {
                DUserResponse dUser = new DUserResponse();
                dUser.setUserName(ui.getUserName());
                dUser.setAvatarUrl(ui.getAvatarUrl());
                return dUser;
            }).collect(Collectors.toList());
            response.setDUserResponses(dUserResponses);

            dialogueResponses.add(response);
        }

        return dialogueResponses;
    }

    @Override
    public Integer getfrienddialogue(Integer userId, Integer friendId) {
        // 查找userId参与的所有会话id
        QueryWrapper<DialogueUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DialogueUser::getUserId, userId);
        List<Integer> dialogueIds = dialogueUserMapper.selectList(queryWrapper).stream()
                .map(DialogueUser::getDialogueId)
                .collect(Collectors.toList());

        // 检查每个会话是否只包含userId和friendId两个用户
        // 找会话，如果不存在则创建新对话
        return dialogueIds.stream()
                .filter(dialogueId -> {
                    // 查询该会话下的所有用户ID
                    QueryWrapper<DialogueUser> memberQuery = new QueryWrapper<>();
                    memberQuery.lambda().eq(DialogueUser::getDialogueId, dialogueId);
                    List<Integer> members = dialogueUserMapper.selectList(memberQuery).stream()
                            .map(DialogueUser::getUserId)
                            .collect(Collectors.toList());

                    // 判断是否恰好包含两个用户，且就是userId和friendId
                    return members.size() == 2 &&
                            members.contains(userId) &&
                            members.contains(friendId);
                })
                .findFirst() // 找到第一个符合条件的会话
                .orElseGet(() -> {
                    // 开启事务保证数据一致性
                    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
                    try {
                        // 创建新对话
                        Dialogue newDialogue = new Dialogue();
                        // 设置对话属性（如果有其他必要属性）
                        dialogueMapper.insert(newDialogue);
                        Integer newDialogueId = newDialogue.getId();

                        // 添加第一个用户到对话
                        DialogueUser user1 = new DialogueUser();
                        user1.setDialogueId(newDialogueId);
                        user1.setUserId(userId);
                        dialogueUserMapper.insert(user1);

                        // 添加第二个用户到对话
                        DialogueUser user2 = new DialogueUser();
                        user2.setDialogueId(newDialogueId);
                        user2.setUserId(friendId);
                        dialogueUserMapper.insert(user2);

                        // 提交事务
                        transactionManager.commit(status);
                        return newDialogueId;
                    } catch (Exception e) {
                        // 回滚事务
                        transactionManager.rollback(status);
                        log.error("创建对话失败", e);
                        throw new RuntimeException("创建对话失败", e);
                    }
                });
    }

    @Override
    public List<Integer> getUserId(Integer dialogueId) {
        QueryWrapper<DialogueUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DialogueUser::getDialogueId,dialogueId);
        List<Integer> userIds = dialogueUserMapper.selectList(queryWrapper).stream()
                .map(DialogueUser::getUserId)
                .collect(Collectors.toList());
        return userIds;
    }
}
